import { Injectable, Inject, NotFoundException } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import * as COS from 'cos-nodejs-sdk-v5';
import { FileRecord } from './entities/file-record.entity';

@Injectable()
export class OssService {
  constructor(
    @Inject('COS_CLIENT') private cosClient: COS,
    private configService: ConfigService,
    @InjectRepository(FileRecord)
    private fileRecordRepo: Repository<FileRecord>,
  ) { }

  private getBucket() {
    return this.configService.get('oss.bucket');
  }

  private getRegion() {
    return this.configService.get('oss.region');
  }

  private getBaseUrl() {
    return this.configService.get('oss.baseUrl');
  }

  // 上传文件并记录到数据库
  async uploadFile(
    userId: number,
    originalName: string,
    content: Buffer,
    mimeType: string,
    folder = 'uploads',
  ) {
    // 生成唯一文件名（避免冲突）
    const filename = `${Date.now()}-${Math.random().toString(36).substring(2, 10)}-${originalName}`;
    const ossKey = `${folder}/${filename}`;

    // 上传到OSS
    await new Promise((resolve, reject) => {
      this.cosClient.putObject(
        {
          Bucket: this.getBucket(),
          Region: this.getRegion(),
          Key: ossKey,
          Body: content,
          ContentType: mimeType,
        },
        (err, data) => {
          if (err) reject(err);
          else resolve(data);
        },
      );
    });

    // 生成访问URL
    const url = `${this.getBaseUrl()}/${ossKey}`;

    // 记录到数据库
    const fileRecord = this.fileRecordRepo.create({
      userId,
      ossKey,
      originalName,
      mimeType,
      size: content.length,
      url,
    });
    await this.fileRecordRepo.save(fileRecord);

    return {
      url,
      ossKey,
      record: fileRecord,
    };
  }

  // 删除文件（同时删除数据库记录）
  async deleteFile(userId: number, ossKey: string) {
    // 先检查记录是否存在且属于当前用户
    const record = await this.fileRecordRepo.findOne({
      where: { ossKey, userId },
    });
    if (!record) {
      throw new NotFoundException('文件不存在或无权删除');
    }

    // 从OSS删除
    await new Promise((resolve, reject) => {
      this.cosClient.deleteObject(
        {
          Bucket: this.getBucket(),
          Region: this.getRegion(),
          Key: ossKey,
        },
        (err, data) => {
          if (err) reject(err);
          else resolve(data);
        },
      );
    });

    // 从数据库删除记录
    await this.fileRecordRepo.remove(record);
    return { success: true, message: '文件已删除' };
  }

  // 查询用户的文件列表
  async getUserFiles(userId: number, prefix = '') {
    const query = this.fileRecordRepo.createQueryBuilder('file')
      .where('file.userId = :userId', { userId });

    if (prefix) {
      query.andWhere('file.ossKey LIKE :prefix', { prefix: `${prefix}%` });
    }

    return query.orderBy('file.createdAt', 'DESC').getMany();
  }

  // 获取文件访问URL
  getFileUrl(ossKey: string) {
    return `${this.getBaseUrl()}/${ossKey}`;
  }
}